-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Feature: implement swtpm in runc #4855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Stefan Berger <[email protected]>
This patch adds vTPM support for Linux to libcontainer. The functionality is based on a recently added vtpm_proxy driver, which is becoming available in Linux 4.8. The driver provides /dev/vtpmx, on which an ioctl is called that spawns a TPM device in the host's /dev directory and returns an anonymous file-descriptor on which a TPM emulator can listen for TPM commands. If we for example created /dev/tpm12 on the host we make this device available as /dev/tpm0 inside the container. We also add its major and minor numbers to the device cgroup. We implement a VTPM class that allows us to create the device and starts a TPM emulator 'swtpm', to which it passes the anonymous file descriptor. Besides that, the user can choose to have the vTPM create certificates in a step that simulates TPM manufacturing. We do this by calling the external swtpm_setup program, which is part of the swtpm project. VTPM support is added inside the JSON configuration as follows: [...] "linux": { "resources": { "devices": [ { "allow": false, "access": "rwm" } ] , "vtpms": [ { "statePath": "/tmp/tpm-1", "createCerts": true }, ] }, [...] This JSON markup makes a single TPM available inside the created container. o The statPath parameter indicates the directory where the TPM emulator 'swtpm' writes the state of the TPM device to. o The createCerts parameter indicates that certificates for the TPM are to be created. The current implementation does not support checkpointing, so checkpointing of a container with an attached vTPM is prevented. The swtpm project is available here : https://github.com/stefanberger/swtpm The libtpms project is available here: https://github.com/stefanberger/libtpms Signed-off-by: Stefan Berger <[email protected]>
Create an AppArmor profile and apply it so that swtpm runs with an AppArmor profile. Signed-off-by: Stefan Berger <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
On systems supporting SELinux run swtpm with an SELinux label applied. Also label the required files in the state directory. Signed-off-by: Stefan Berger <[email protected]>
Add test cases for testing TPM 1.2 and TPM 2 by creating, stopping, restarting, and destroying it. Signed-off-by: Stefan Berger <[email protected]>
Call 'swtpm chardev --print-capabilities' to get the supported capabilites from swtpm. An JSON object is printed by swtpm that we unmarshal and we pick the 'features' part from it that is an array of strings indicating what this version of swtpm supports. This option was added in v0.2. For older versions of swtpm we return an empty array. Signed-off-by: Stefan Berger <[email protected]>
We need to startup the TPM as part of starting swtpm so that the Linux driver can successfully send its initial command to the vTPM and does not log a failure and then do the startup itself. Signed-off-by: Stefan Berger <[email protected]>
This patch adds support for encrypting the vTPM state by allowing a user to pass a password to swtpm_setup and swtpm. Signed-off-by: Stefan Berger <[email protected]>
Add /sys/devices/virtual/tpm to the mask paths to avoid isolation issues via sysfs for TPM 1.2 Signed-off-by: Stefan Berger <[email protected]>
Put vTPMs into a container's cgroup to limit their CPU usage. Signed-off-by: Stefan Berger <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
Signed-off-by: Efim Verzakov <[email protected]>
…th swtpm_cuse issue Signed-off-by: Efim Verzakov <[email protected]>
A virtual TPM sounds interesting to me. Is there a runtime-spec PR for this already? That will be needed too. I haven't had a look at the code yet :) |
Hello! Thank you for your interest. There is a link for runtime-spec PR. In order to simplify runc/runtime-spec code changes, we have reconsidered our current approach to pass vTPM devices. We will be grateful if you review it as a runc maintainer. |
This patch series adds a vTPM support for Linux to libcontainer.
The functionality is based on swtpm_cuse binary to create cuse device on which a TPM emulator listen for TPM commands. If we for example want to create vtpmName device then we make this device available as /dev/tpm + vtpmName inside the container. We also add its major and minor numbers to the device cgroup.
We implement a VTPM class that allows us to create the device and starts a TPM emulator 'swtpm_cuse'. Besides that, the user can choose to have the vTPM create certificates in a step that simulates TPM manufacturing. We do this by calling the external swtpm_setup program, which is a part of the swtpm project.
vTPM support is added inside the JSON configuration as follows:
This JSON markup makes a single TPM available inside the created container:
Users can have a requirement to create 2 containers with separated vTPM devices with the same vtpmName in the container rootfs. In the host the created vTPM will have the devpath like that: /dev/tpm + hash of runc root + "-" + containerName + "-" + vtpmName. vTPM devices require runc to be run by root. If runc is running in non-default user namespace or have user namespace in config, then /dev/tpm + hash of runc root + "-" + containerName + "-" + vtpmName will be passed to the container instead of /dev/tpm + vtpmName.
There are several checks to be sure that vTPM devices are unique and won't miss the state between themselves:
The third check is done by starting 'swtpm_cuse' by checking two file locks on '.runc-lock' and '.lock' in the state dir.
In order to run unit / integration tests in the docker container you should also add vtpmMajor and vtpmMinor parameters to the vTPM spec, add them to the cgroup allow rule and pass /dev/cuse device. This is done because tmpfs is usually mounted on the container's /dev/path that's why the new devices won't be propagated to the test container. Also, swtpm.sh script is added to download swtpm and libtpms source code to the test container and build it. google/go-tpm is added to the dependency list because it is used in tpm-helper binary to check vTPM devices in the integration tests.
This PR is based on the previous PR.
The swtpm project is available here
The libtpms project is available here
Runc issue
Runtime-spec PR